package comp512.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JToggleButton;
import javax.swing.SpringLayout;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import comp512.classes.Answer;
import comp512.classes.DB;
import comp512.classes.Question;
import comp512.classes.Server;
import javax.swing.JTextField;

@SuppressWarnings("serial")
public class ServerGUI_Main extends JFrame {

	private JPanel contentPane;
	private JLabel lblStatus;
	private JLabel lblCount;
	private Server server;
	private JTextField txtIP;
	private JTextField txtServerPort;
	private static ServerGUI_Main instance = null;

	public static ServerGUI_Main getInstance() {
		if (instance == null)
			instance = new ServerGUI_Main();

		return instance;
	}

	/**
	 * Create the frame.
	 */
	public ServerGUI_Main() {
		if (instance == null)
			instance = this;
		setPreferredSize(new Dimension(200, 200));
		setMaximumSize(new Dimension(200, 200));
		setMinimumSize(new Dimension(200, 200));
		setResizable(false);
		setType(Type.UTILITY);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 260, 250);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		contentPane.add(splitPane, BorderLayout.CENTER);

		JPanel pnlServerButton = new JPanel();
		pnlServerButton.setMinimumSize(new Dimension(10, 30));
		splitPane.setLeftComponent(pnlServerButton);
		pnlServerButton.setLayout(new BorderLayout(0, 0));

		final JToggleButton tglbtnStartServer = new JToggleButton(
				"Start Server");
		tglbtnStartServer.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
				if (tglbtnStartServer.isSelected()) {
					try {
						if (server != null)
							server.startServer();
						else {
							server = new Server();
							server.startServer();
						}
						txtIP.setText(server.getAddress());
						txtServerPort.setText(server.getPort());
						lblStatus.setText("Running");
					} catch (Exception e) {
						lblStatus.setText("An error Occured");
					}
					tglbtnStartServer.setText("Stop Server");
				} else {
					// if (server != null)
					// server.stopServer();
					tglbtnStartServer.setText("Start Server");
					lblStatus.setText("Stopped");
					if (server != null)
						server.clearPlayers();
					lblCount.setText("0");
				}
			}
		});
		pnlServerButton.add(tglbtnStartServer, BorderLayout.CENTER);

		JPanel pnlServerStatus = new JPanel();
		splitPane.setRightComponent(pnlServerStatus);
		SpringLayout sl_pnlServerStatus = new SpringLayout();
		pnlServerStatus.setLayout(sl_pnlServerStatus);

		JLabel lblServerStatusStatic = new JLabel("Server Status");
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH,
				lblServerStatusStatic, 11, SpringLayout.NORTH, pnlServerStatus);
		lblServerStatusStatic.setBorder(new EmptyBorder(5, 5, 5, 5));
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST,
				lblServerStatusStatic, 10, SpringLayout.WEST, pnlServerStatus);
		pnlServerStatus.add(lblServerStatusStatic);

		lblStatus = new JLabel("<STATUS>....");
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, lblStatus, 4,
				SpringLayout.NORTH, lblServerStatusStatic);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, lblStatus, 36,
				SpringLayout.EAST, lblServerStatusStatic);
		sl_pnlServerStatus.putConstraint(SpringLayout.EAST, lblStatus, -10,
				SpringLayout.EAST, pnlServerStatus);
		lblStatus.setBorder(new LineBorder(new Color(0, 0, 0)));
		pnlServerStatus.add(lblStatus);

		JLabel lblClientsConnected = new JLabel("Clients Connected");
		lblClientsConnected.setBorder(new EmptyBorder(5, 5, 5, 5));
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH,
				lblClientsConnected, 8, SpringLayout.SOUTH,
				lblServerStatusStatic);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST,
				lblClientsConnected, 0, SpringLayout.WEST,
				lblServerStatusStatic);
		pnlServerStatus.add(lblClientsConnected);

		lblCount = new JLabel("<COUNT>");
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, lblCount, 15,
				SpringLayout.SOUTH, lblStatus);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, lblCount, 0,
				SpringLayout.WEST, lblStatus);
		sl_pnlServerStatus.putConstraint(SpringLayout.EAST, lblCount, -10,
				SpringLayout.EAST, pnlServerStatus);
		lblCount.setMinimumSize(new Dimension(70, 14));
		lblCount.setMaximumSize(new Dimension(70, 14));
		lblCount.setPreferredSize(new Dimension(70, 14));
		lblCount.setBorder(new LineBorder(new Color(0, 0, 0)));
		pnlServerStatus.add(lblCount);

		JButton btnQuestionBank = new JButton("Question Bank");
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, btnQuestionBank,
				69, SpringLayout.WEST, pnlServerStatus);
		sl_pnlServerStatus.putConstraint(SpringLayout.SOUTH, btnQuestionBank,
				-10, SpringLayout.SOUTH, pnlServerStatus);
		btnQuestionBank.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ServerGUI_QuestionBank qb = new ServerGUI_QuestionBank();

				qb.setVisible(true);
			}
		});
		pnlServerStatus.add(btnQuestionBank);

		JLabel lblServerIp = new JLabel("Server IPv4");
		lblServerIp.setBorder(new EmptyBorder(5, 5, 5, 5));
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, lblServerIp, 6,
				SpringLayout.SOUTH, lblClientsConnected);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, lblServerIp, 0,
				SpringLayout.WEST, lblServerStatusStatic);
		pnlServerStatus.add(lblServerIp);

		txtIP = new JTextField();
		sl_pnlServerStatus.putConstraint(SpringLayout.SOUTH, lblCount, -15,
				SpringLayout.NORTH, txtIP);
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, txtIP, 4,
				SpringLayout.NORTH, lblServerIp);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, txtIP, 0,
				SpringLayout.WEST, lblStatus);
		sl_pnlServerStatus.putConstraint(SpringLayout.EAST, txtIP, 0,
				SpringLayout.EAST, lblStatus);
		txtIP.setBorder(new LineBorder(Color.BLACK));
		txtIP.setEditable(false);
		pnlServerStatus.add(txtIP);
		txtIP.setColumns(10);

		JLabel lblServerPort = new JLabel("Server Port");
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, lblServerPort, 6,
				SpringLayout.SOUTH, lblServerIp);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, lblServerPort, 0,
				SpringLayout.WEST, lblServerStatusStatic);
		lblServerPort.setBorder(new EmptyBorder(5, 5, 5, 5));
		pnlServerStatus.add(lblServerPort);

		txtServerPort = new JTextField();
		sl_pnlServerStatus.putConstraint(SpringLayout.NORTH, txtServerPort, 4,
				SpringLayout.NORTH, lblServerPort);
		sl_pnlServerStatus.putConstraint(SpringLayout.WEST, txtServerPort, 0,
				SpringLayout.WEST, lblStatus);
		sl_pnlServerStatus.putConstraint(SpringLayout.EAST, txtServerPort, 0,
				SpringLayout.EAST, lblStatus);
		txtServerPort.setBorder(new LineBorder(Color.BLACK));
		txtServerPort.setEditable(false);
		pnlServerStatus.add(txtServerPort);
		txtServerPort.setColumns(10);

	}

	public void init() {
		// System.out.println("Populating Questions.");
		DB db = DB.getInstance();
		FileReader reader = null;
		BufferedReader br = null;
		try {
			// System.out.println("Reading File...");
			reader = new FileReader("src/comp512/resources/dataset.csv");
			br = new BufferedReader(reader);
			String curLine;
			while ((curLine = br.readLine()) != null) {
				String[] data = curLine.replaceAll("@", "").split(";");
				if (data.length < 2)
					System.out.println("Data invalid: " + curLine);
				Question quest = new Question(data[0].trim());
				for (int i = 1; i < data.length; i++) {
					String s = data[i];
					if (s.contains(",")) {
						Answer an = new Answer();
						String[] spts = s.split(",");
						an.setAnswer(spts[0].trim());
						int weight = -1;
						try {
							weight = Integer.parseInt(spts[1].trim());
						} catch (NumberFormatException nfx) {
							System.err.println(nfx.getMessage());
						}
						an.setWeight(weight);
						quest.addAnswer(an);
					}
				}
				db.addQuestion(quest);
			}
			// System.out.println("Done reading. Total Questions: " +
			// db.getQuestionCount());
		} catch (FileNotFoundException fnf) {
			System.out.println("FNF: " + fnf.getMessage());
			fnf.getStackTrace();
		} catch (IOException iox) {
			System.out.println("IOX: " + iox.getMessage());
			iox.getStackTrace();
		} finally {
			try {
				br.close();
				// System.out.println("File Closed");
			} catch (IOException e) {
				// System.out.println("Total Questions: " +
				// db.getQuestionCount());
			}
		}
		lblStatus.setText("Stopped");
		lblCount.setText("0");
	}

	public boolean setCounter(String clients) {
		try {
			System.out.println("updating counter to " + clients);
			lblCount.setText(clients);
			this.validate();
			this.repaint(100);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public int getCounter() {
		try {
			return Integer.parseInt(lblCount.getText());
		} catch (NumberFormatException nfx) {
			System.err.println(nfx.getMessage());
			nfx.printStackTrace();
		}
		return 0;
	}
}
